6.2.14 多层架构的镜像

Docker最值得称赞的一点就是使用方便。例如,运行一个应用就像拉取镜像并运行容器这么简单。无须担心安装、依赖或者配置的问题。开箱即用。

但是,随着Docker的发展,事情开始变得复杂——尤其是在添加了新平台和架构之后,例如Windows、ARM以及s390x。读者会突然发现,在拉取镜像并运行之前,需要考虑镜像是否与当前运行环境的架构匹配,这破坏了Docker的流畅体验。

多架构镜像(Multi-architecture Image)的出现解决了这个问题!

Docker(镜像和镜像仓库服务)规范目前支持多架构镜像。这意味着某个镜像仓库标签(repository:tag)下的镜像可以同时支持64位Linux、PowerPC Linux、64位Windows和ARM等多种架构。简单地说,就是一个镜像标签之下可以支持多个平台和架构。下面通过实操演示该特性。

为了实现这个特性,镜像仓库服务API支持两种重要的结构:Manifest列表(新)和Manifest。

Manifest列表是指某个镜像标签支持的架构列表。其支持的每种架构,都有自己的Mainfest定义,其中列举了该镜像的构成。

图6.9使用 Golang 官方镜像作为示例。图左侧是Manifest列表,其中包含了该镜像支持的每种架构。Manifest列表的每一项都有一个箭头,指向具体的Manifest,其中包含了镜像配置和镜像层数据。

31.png

图6.9  `Golang` 官方镜像

在具体操作之前,先来了解一下原理。

假设要在Raspberry Pi(基于ARM架构的Linux)上运行Docker。在拉取镜像的时候,Docker客户端会调用Docker Hub镜像仓库服务相应的API完成拉取。如果该镜像有Mainfest列表,并且存在Linux on ARM这一项,则Docker Client就会找到ARM架构对应的Mainfest并解析出组成该镜像的镜像层加密ID。然后从Docker Hub二进制存储中拉取每个镜像层。

下面的示例就展示了多架构镜像是如何在拉取官方Golang镜像(支持多架构)时工作的,并且通过一个简单的命令展示了Go的版本和所在主机的CPU架构。需要注意的是,两个例子都使用相同的命令 docker container run 。不需要告知Docker具体的镜像版本是64位Linux还是64位Windows。示例中只运行了普通的命令,选择当前平台和架构所需的正确镜像版本是有由Docker完成的。

64位Linux示例如下。

$ docker container run --rm golang go version
Unable to find image 'golang:latest' locally
latest: Pulling from library/golang
723254a2c089: Pull complete
<Snip>
39cd5f38ffb8: Pull complete
Digest: sha256:947826b5b6bc4...
Status: Downloaded newer image for golang:latest
go version go1.9.2 linux/amd64

64位Windows示例如下。

PS> docker container run --rm golang go version
Using default tag: latest
latest: Pulling from library/golang
3889bb8d808b: Pull complete
8df8e568af76: Pull complete
9604659e3e8d: Pull complete
9f4a4a55f0a7: Pull complete
6d6da81fc3fd: Pull complete
72f53bd57f2f: Pull complete
6464e79d41fe: Pull complete
dca61726a3b4: Pull complete
9150276e2b90: Pull complete
cd47365a14fb: Pull complete
1783777af4bb: Pull complete
3b8d1834f1d7: Pull complete
7258d77b22dd: Pull complete
Digest: sha256:e2be086d86eeb789...e1b2195d6f40edc4
Status: Downloaded newer image for golang:latest
go version go1.9.2 windows/amd64

前面的操作包括从Docker Hub拉取 Golang 镜像,以容器方式启动,执行 go version 命令,并且输出Go的版本和主机OS / CPU架构信息。每个示例的最后一行都展示了 go version 命令的输出内容。可以看到两个示例使用了完全相同的命令,但是Linux示例中拉取的是 linux/amd64 镜像,而Windows示例中拉取的是 windows/amd64 镜像。

在编写本书的时候,所有官方镜像都支持 Manifest列表 。但是,全面支持各种架构的工作仍在推进当中。

创建支持多架构的镜像需要镜像的发布者做更多的工作。同时,某些软件也并非跨平台的。在这个前提下, Manifest列表 是可选的——在没有 Manifest列表 的情况下,镜像仓库服务会返回普通的 Manifest

results matching ""

    No results matching ""